package com.wyz.socket.core.base.frame.send;

import com.wyz.socket.core.base.IoArgs;
import com.wyz.socket.core.base.frame.Frame;

import java.io.IOException;

public abstract class AbstractSendFrame extends Frame {

    volatile byte headerRemaining = Frame.FRAME_HEADER_LENGTH;

    volatile int bodyRemaining;

    public AbstractSendFrame(int length, byte type, byte flag, short identifier) {
        super(length, type, flag, identifier);
        bodyRemaining = length;
    }

    public AbstractSendFrame(byte[] heartbeatData) {
        super(heartbeatData);
    }

    @Override
    public synchronized boolean handle(IoArgs args) throws IOException {
        try {
            args.limit(headerRemaining + bodyRemaining);
            args.startWriting();

            if (headerRemaining > 0 && args.hasRemaining()) {
                headerRemaining -= consumeHeader(args);
            }
            if (headerRemaining == 0) {
                if (bodyRemaining > 0 && args.hasRemaining()) {
                    bodyRemaining -= consumeBody(args);
                }
            }
            return headerRemaining == 0 && bodyRemaining == 0;
        } finally {
            args.endWriting();
        }

    }

    protected byte consumeHeader(IoArgs args) throws IOException {
        int count = headerRemaining;
        int offset = header.length - count;
        return (byte) args.readFrom(header, offset, count);
    }

    protected abstract int consumeBody(IoArgs args) throws IOException;

    public synchronized boolean isSending() {
        return headerRemaining < Frame.FRAME_HEADER_LENGTH;
    }

    @Override
    public int getUnConsumeLength() {
        return headerRemaining+bodyRemaining ;
    }
}
